﻿#pragma once

#include <QObject>
#include "ControlItem.h"
#include <QList>
#include "DefineItemType.h"
#include <QtMath>

//******基类******
class ItemBase : public QObject, public QGraphicsItemGroup
{
    Q_OBJECT

public:
    explicit ItemBase(QPointF p, DefineItemType type);
    virtual void onPointPush(QPointF p){}
    virtual void onPointMove(QPointF p){}
    virtual void onCreateFinish(){this->setFocus();}
    virtual bool itemUpdate(int index){return true;}
    DefineItemType getType() const {return itemType;}
    void setDescribe(const QString& txt){itemDescribe = txt;}
    QString describe() const {return itemDescribe;}

public:
    static QMap<DefineItemType, QString> mapItemTypeName;
    static qreal contrSize;
    double scale;
    QVector<ControlItem*> controlList;

protected:
    virtual void focusInEvent(QFocusEvent* event) override;
	virtual void focusOutEvent(QFocusEvent* event) override;
    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;


protected:
    DefineItemType itemType;
	QColor fillColor;
	QPen thisPen;
    QString itemDescribe = "";
    int nextIndexPoint = 0;
    QPointF center;
};

//******绘制结果数据******
class ItemDraw : public ItemBase
{
	Q_OBJECT
public:
    struct ItemDrawText{
        QPointF point;
        QString text;
        QColor color;
        double size;
        explicit ItemDrawText():point(QPoint(0, 0)), text(""), color(QColor(255, 0, 0)), size(20.0){
        }
        explicit ItemDrawText(QPointF p, QString t, QColor c = QColor(255), double s = 20){
            point = p;
            text = t;
            color = c;
            size = s;
        }
    };
public:
    explicit ItemDraw();
    void addLine(QLineF line);
    void addCircle(QPointF center, float radius);
    void addRect(QRectF rect);
    void addRegion(QVector<QPointF>& region);
    void addXld(QVector<QPointF>& xld);
    void addRectR(QPointF center, double phi, double len1, int len2);
    void addPoint(QPointF point);
    void addText(ItemDrawText txt);
    void clearAll();
	void refresh();
    void setDispROI(QRectF& Rec) {returnRec = Rec;};

protected:
	virtual QRectF boundingRect() const override;
	void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);

private:
	QRectF returnRec;
    QVector<QLineF> lineList;
    QVector<QLineF> roiList;
    QVector<QLineF> xldList;
    QVector<QRectF> circleList;
    QVector<QRectF> rectList;
    QVector<QPointF> pointList;
    QVector<QVector<QPointF>> rectRList;
    QVector<ItemDrawText> txtList;
};

//******矩形******
class ItemRect : public ItemBase
{
	Q_OBJECT
public:
    explicit ItemRect(qreal x, qreal y, qreal width, qreal height);
    explicit ItemRect();
    void getDefObject(DefRect& MRect);
    DefRect getDefObject();

public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
    bool itemUpdate(int index) override;

protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter* painter,
		const QStyleOptionGraphicsItem* option,
		QWidget* widget) override;
};

//******旋转矩形******
class ItemRectR : public ItemBase
{
	Q_OBJECT

public:
    explicit ItemRectR(qreal x, qreal y, qreal Lenth1, qreal Lenth2, qreal Pi);
    explicit ItemRectR();
    void getDefObject(DefRectR& MRRect);
    DefRectR getDefObject();

public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
    bool itemUpdate(int index) override;

protected:
	virtual QRectF boundingRect() const override;
    virtual void paint(QPainter* painter,
        const QStyleOptionGraphicsItem* option,
        QWidget* widget) override;

protected:
    qreal phi = 0;
	qreal lenth1 = 0;
	qreal lenth2 = 0;
    QPointF pa1;
	QPointF pa2;
	QPointF pArrow;
    double posControlPoint2 = -M_PI_2;
};

//******多边形******
class ItemPolygon :public ItemBase
{
	Q_OBJECT

public:
    ItemPolygon(QList<QPointF> lstPoint);
    ItemPolygon();
    QPointF getCentroPoint(QList<QPointF> list);
	void getMaxLength();
    void getDefObject(DefPolygon& DefPolygon);
    DefPolygon getDefObject();

public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
    void onCreateFinish() override;
    bool itemUpdate(int index) override;

protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter* painter,
		const QStyleOptionGraphicsItem* option,
		QWidget* widget) override;

private:
    bool isPushFinish = false;
    qreal radius;
};

//******圆******
class ItemCircle :public ItemBase
{
	Q_OBJECT

public:
	ItemCircle(qreal x, qreal y, qreal R);
    ItemCircle();
    void getDefObject(DefCircle& Cir);
    DefCircle getDefObject();
public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
    bool itemUpdate(int index) override;
protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter* painter,
		const QStyleOptionGraphicsItem* option,
		QWidget* widget) override;
private:
	qreal radius;
};

//******同心圆******
class ItemCircleC :public ItemBase
{
	Q_OBJECT

public:	
	ItemCircleC(qreal x, qreal y, qreal radiusInner, qreal radiusOuter);
    ItemCircleC();
    void getDefObject(DefCircleC& CCir);
    DefCircleC getDefObject();

public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
    bool itemUpdate(int index) override;
protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter* painter,
		const QStyleOptionGraphicsItem* option,
		QWidget* widget) override;
private:
	qreal radiusInner;
    qreal radiusOuter;
};

//******卡尺******
class ItemCaliper :public ItemBase
{
	Q_OBJECT

public:
    ItemCaliper(qreal x1, qreal y1, qreal x2, qreal y2, qreal height);
    ItemCaliper();
    void getDefObject(DefCaliper& cp);
    DefCaliper getDefObject();
public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
    bool itemUpdate(int index) override;
protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter* painter,
		const QStyleOptionGraphicsItem* option,
        QWidget* widget) override;
private:
	QPointF pointStart;
	QPointF pointEnd;
	qreal height;
    qreal phi;
    qreal length;
};

//******直线******
class ItemLine :public ItemBase
{
    Q_OBJECT
public:
    ItemLine(qreal x1, qreal y1, qreal x2, qreal y2);
    ItemLine();
    void getDefObject(DefLine& cp);
    DefLine getDefObject();
public slots:
    void onPointPush(QPointF p) override;
    void onPointMove(QPointF p) override;
protected:
    virtual QRectF boundingRect() const override;
    bool itemUpdate(int index) override;
    virtual void paint(QPainter* painter,
                       const QStyleOptionGraphicsItem* option,
                       QWidget* widget) override;
private:
    QPointF pointStart;
    QPointF pointEnd;
};

//**************************************点*********************************************************
class ItemPoint:public ItemBase
{
    Q_OBJECT
public:
    ItemPoint(qreal x, qreal y);
    ItemPoint(DefPoint defPoint);
    ItemPoint();
    void getDefObject(DefPoint& point);
    DefPoint getDefObject();
public slots:
    void onPointPush(QPointF p) override;
protected:
    virtual QRectF boundingRect() const override;
    bool itemUpdate(int index=-1) override;
    virtual void paint(QPainter* painter,
                       const QStyleOptionGraphicsItem* option,
                       QWidget* widget) override;
};
